package com.example.permission.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.example.common.utils.Assert;
import com.example.permission.entity.Permission;
import com.example.permission.entity.SystemRole;
import com.example.permission.entity.SystemRolePermission;
import com.example.permission.mapper.SystemPermissionMapper;
import com.example.permission.mapper.SystemRoleMapper;
import com.example.permission.mapper.SystemRolePermissionMapper;
import com.example.permission.model.req.SystemRoleDTO;
import com.example.permission.model.resp.SystemRoleVO;
import com.example.permission.service.SystemRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author qwer3
 * @version 1.0.0
 * @create 2025/11/16 11:27
 */
@Service
@RequiredArgsConstructor
public class SystemRoleServiceImpl implements SystemRoleService {
    private final SystemRoleMapper systemRoleMapper;
    private final SystemPermissionMapper systemPermissionMapper;
    private final SystemRolePermissionMapper rolePermissionMapper;

    @Override
    public void createOrModifyRole(SystemRoleDTO systemRoleDTO) {
        // 用户权限
        boolean isNewRole = false;
        String roleId = systemRoleDTO.getRoleId();
        SystemRole systemRole;
        if (systemRoleDTO.getRoleId() == null) {
            roleId = UUID.randomUUID().toString();
            isNewRole = true;
        } else {
            SystemRole dbSystemRole = systemRoleMapper.querySystemRoleByRoleId(roleId);
            Assert.notNull(dbSystemRole, "角色不存在");
            roleId = dbSystemRole.getRoleId();
        }
        systemRole = SystemRole.builder()
                .roleId(roleId)
                .name(systemRoleDTO.getName())
                .description(systemRoleDTO.getDescription())
                .build();

        // 查询系统权限配置
        List<Permission> permissionList = systemPermissionMapper.getSystemPermission();
        Map<String, Permission> permissionMap = permissionList.stream()
                .filter(perm -> perm.getName() != null)
                .collect(Collectors.toMap(
                        Permission::getName,      // key：权限Name
                        perm -> perm,           // value：Permission 对象本身
                        (existing, replacement) -> existing // 如果有重复 key，保留第一个（或根据业务决定）
                ));

        // 查询角色已保存的权限，过滤已经存在的权限
        // 若用户权限已存在，过滤；若用户权限不存在，保留后续插入；若用户权限被移除，删除对应权限
        List<String> permissions = systemRoleDTO.getPermissions();

        // 系统过滤
        Set<String> existingSystemPermissionSet = permissionList.stream()
                .map(Permission::getPermissionId).collect(Collectors.toSet());
        Set<String> newPermissionSet = permissions.stream()
                .filter(p -> !existingSystemPermissionSet.contains(p))
                .collect(Collectors.toSet());

        // 用户已保存过滤
        List<String> toInsert;
        if (!isNewRole) {
            List<String> rolePermissionList = rolePermissionMapper.querySystemRoleDetailByRoleId(roleId);
            Set<String> existingPermissionSet = new HashSet<>(rolePermissionList);

            // 1. 需要新增的权限：存在于 new 但不存在于 existing
            toInsert = permissions.stream()
                    .filter(p -> !existingPermissionSet.contains(p))
                    .toList();

            // 2. 需要删除的权限：存在于 existing 但不存在于 new
            List<String> toDelete = rolePermissionList.stream()
                    .filter(p -> !newPermissionSet.contains(p))
                    .toList();

            // 删除失效的权限
            if (CollUtil.isNotEmpty(toDelete)) {
                List<String> toDeletePermissionIds = new ArrayList<>();
                for (String toDelPermission : toDelete) {
                    toDeletePermissionIds.add(permissionMap.get(toDelPermission).getPermissionId());
                }
                rolePermissionMapper.batchRemoveRolePermission(roleId, toDeletePermissionIds);
            }
        } else {
            toInsert = new ArrayList<>(newPermissionSet);
        }

        // 根据角色权限保存配置
        List<SystemRolePermission> systemRolePermissions = new ArrayList<>();
        for (String permission : toInsert) {
            Permission validPermission = permissionMap.get(permission);
            if (validPermission != null) {
                SystemRolePermission systemRolePermission = SystemRolePermission.builder()
                        .permissionId(validPermission.getPermissionId())
                        .roleId(roleId)
                        .build();
                systemRolePermissions.add(systemRolePermission);
            }
        }

        // 保存角色 和 角色权限
        systemRoleMapper.saveOrModifyRole(systemRole);
        if (CollUtil.isNotEmpty(systemRolePermissions)) {
            rolePermissionMapper.batchSaveRolePermission(systemRolePermissions);
        }
    }

    @Override
    public List<SystemRoleVO> getSystemRole() {
        List<SystemRole> systemRoles = systemRoleMapper.querySystemRoleList();
        return systemRoles.stream().map(systemRole -> BeanUtil.copyProperties(systemRole, SystemRoleVO.class)).toList();
    }

    @Override
    public SystemRoleDTO getSystemRoleDetail(String roleId) {
        SystemRole systemRole = systemRoleMapper.querySystemRoleByRoleId(roleId);
        Assert.notNull(systemRole, "角色不存在");
        List<String> rolePermissionList = rolePermissionMapper.querySystemRoleDetailByRoleId(roleId);
        return SystemRoleDTO.builder()
                .roleId(systemRole.getRoleId())
                .description(systemRole.getDescription())
                .name(systemRole.getName())
                .permissions(rolePermissionList)
                .build();
    }

    @Override
    public void deleteRole(String roleId) {
        systemRoleMapper.deleteRoleByRoleId(roleId);
        rolePermissionMapper.deleteRoleByRoleId(roleId);
    }
}
